<template>
  <div class="expression-editor">
    <!-- 表达式输入框 -->
    <div class="expression-input-container">
      <el-input ref="inputRef" v-model="localValue" type="textarea" :placeholder="placeholder || '请输入表达式...'"
        :readonly="readonly" :rows="3" class="expression-input" @input="handleInput" @keydown="handleKeydown"
        @focus="handleFocus" @blur="handleBlur" />

      <!-- 验证状态指示器 -->
      <div v-if="validationResult" class="validation-indicator">
        <el-icon v-if="validationResult.isValid" class="success-icon">
          <Check />
        </el-icon>
        <el-icon v-else class="error-icon">
          <Close />
        </el-icon>
      </div>
    </div>

    <!-- 操作按钮 -->
    <div class="action-buttons">
      <el-button size="small" @click="validateExpression">
        <el-icon>
          <Check />
        </el-icon>
        校验
      </el-button>
      <el-button size="small" @click="clearExpression">
        <el-icon>
          <Delete />
        </el-icon>
        清空
      </el-button>     
    </div>

    <!-- 错误和警告提示 -->
    <div v-if="validationResult" class="validation-messages">
      <!-- 错误信息 -->
      <div v-if="validationResult && validationResult.errors && validationResult.errors.length > 0"
        class="error-messages">
        <el-alert v-for="(error, index) in validationResult.errors" :key="`error-${index}`" :title="error.message"
          type="error" size="small" :closable="false" show-icon />
      </div>

      <!-- 警告信息 -->
      <div v-if="validationResult && validationResult.warnings && validationResult.warnings.length > 0"
        class="warning-messages">
        <el-alert v-for="(warning, index) in validationResult.warnings" :key="`warning-${index}`"
          :title="warning.message" type="warning" size="small" :closable="true" show-icon />
      </div>
    </div>

    <!-- 变量提示区域 -->
    <div v-if="showVariableHelp" class="variable-help">
      <el-collapse v-model="activeCollapse">
        <!-- 系统变量 -->
        <el-collapse-item v-if="systemVariables?.length" title="系统变量" name="system">
          <div class="variable-list">
            <div v-for="variable in systemVariables" :key="variable.name" class="variable-item"
              @click="insertVariable(variable.name)">
              <span class="variable-name">{{ variable.name }}</span>
              <span class="variable-label">({{ variable.label }})</span>
              <span class="variable-type">{{ variable.type }}</span>
            </div>
          </div>
        </el-collapse-item>

        <!-- 表单变量 -->
        <el-collapse-item v-if="formVariables?.length" title="表单变量" name="form">
          <div class="variable-list">
            <div v-for="variable in formVariables" :key="variable.name" class="variable-item"
              @click="insertVariable(variable.name)">
              <span class="variable-name">{{ variable.name }}</span>
              <span class="variable-label">({{ variable.label }})</span>
              <span class="variable-type">{{ variable.type }}</span>
            </div>
          </div>
        </el-collapse-item>
      </el-collapse>
    </div>

    <!-- 语法文档 -->
    <div v-if="showSyntaxDoc" class="syntax-documentation">
      <el-collapse v-model="activeDocSection">
        <el-collapse-item title="基本操作符" name="operators">
          <div class="doc-content">
            <ul>
              <li><code>==</code> 等于</li>
              <li><code>!=</code> 不等于</li>
              <li><code>&gt;</code> 大于</li>
              <li><code>&lt;</code> 小于</li>
              <li><code>&gt;=</code> 大于等于</li>
              <li><code>&lt;=</code> 小于等于</li>
              <li><code>&amp;&amp;</code> 逻辑与</li>
              <li><code>||</code> 逻辑或</li>
              <li><code>!</code> 逻辑非</li>
            </ul>
          </div>
        </el-collapse-item>

        <el-collapse-item title="字符串函数" name="string-functions">
          <div class="doc-content">
            <ul>
              <li><code>len(str)</code> 获取字符串长度</li>
              <li><code>contains(str, substr)</code> 检查包含</li>
              <li><code>startsWith(str, prefix)</code> 检查前缀</li>
              <li><code>endsWith(str, suffix)</code> 检查后缀</li>
              <li><code>matches(str, pattern)</code> 正则匹配</li>
              <li><code>upper(str)</code> 转大写</li>
              <li><code>lower(str)</code> 转小写</li>
              <li><code>trim(str)</code> 去除空格</li>
            </ul>
          </div>
        </el-collapse-item>

        <el-collapse-item title="日期函数" name="date-functions">
          <div class="doc-content">
            <ul>
              <li><code>now()</code> 获取当前时间</li>
              <li><code>date(str[, format[, timezone]])</code> 解析日期字符串</li>
              <li><code>duration(str)</code> 创建时间间隔</li>
              <li><code>now().Year()</code> 获取年份</li>
              <li><code>now().Month()</code> 获取月份</li>
              <li><code>now().Day()</code> 获取日期</li>
              <li><code>now().Hour()</code> 获取小时</li>
              <li><code>now().Minute()</code> 获取分钟</li>
              <li><code>now().Second()</code> 获取秒数</li>
              <li><code>now().Format("2006-01-02")</code> 格式化日期</li>
              <li><code>now().Add(duration("1h"))</code> 添加时间间隔</li>
              <li><code>now().Before(date("2024-01-01"))</code> 时间比较</li>
            </ul>
          </div>
        </el-collapse-item>

        <el-collapse-item title="数学函数" name="number-functions">
          <div class="doc-content">
            <ul>
              <li><code>abs(x)</code> 绝对值</li>
              <li><code>ceil(x)</code> 向上取整</li>
              <li><code>floor(x)</code> 向下取整</li>
              <li><code>round(x)</code> 四舍五入</li>
              <li><code>max(x, y, ...)</code> 最大值</li>
              <li><code>min(x, y, ...)</code> 最小值</li>
              <li><code>pow(x, y)</code> 幂运算</li>
              <li><code>sqrt(x)</code> 平方根</li>
              <li><code>log(x)</code> 自然对数</li>
              <li><code>sin(x)</code> 正弦值</li>
              <li><code>cos(x)</code> 余弦值</li>
              <li><code>tan(x)</code> 正切值</li>
            </ul>
          </div>
        </el-collapse-item>

        <el-collapse-item title="示例表达式" name="examples">
          <div class="doc-content">
            <h5>基础示例</h5>
            <ul>
              <li><code>user.age &gt;= 18</code> 年龄检查</li>
              <li><code>len(user.name) &gt; 0</code> 名称非空</li>
              <li><code>contains(user.email, "@")</code> 邮箱格式</li>
              <li><code>user.role == "admin"</code> 角色检查</li>
            </ul>

            <h5>日期函数示例</h5>
            <ul>
              <li><code>now().Year() &gt; 2023</code> 年份检查</li>
              <li><code>now().Month() &gt;= 6</code> 月份检查</li>
              <li><code>now().After(date("2023-01-01"))</code> 日期比较</li>
              <li><code>date("2023-12-31").Before(now())</code> 过期检查</li>
            </ul>

            <h5>数学函数示例</h5>
            <ul>
              <li><code>abs(form.salary - 5000) &lt; 1000</code> 薪资范围</li>
              <li><code>max(form.score1, form.score2) &gt;= 80</code> 最高分检查</li>
              <li><code>round(form.amount / 100) * 100 == form.amount</code> 整百检查</li>
              <li><code>sqrt(pow(x, 2) + pow(y, 2)) &lt; 10</code> 距离计算</li>
            </ul>

            <h5>复合表达式</h5>
            <ul>
              <li><code>form.score &gt;= 60 &amp;&amp; form.status == "active"</code> 复合条件</li>
              <li><code>now().Year() &gt; 2023 &amp;&amp; abs(form.salary - 5000) &lt; 1000</code> 日期+数学</li>
            </ul>
          </div>
        </el-collapse-item>
      </el-collapse>
    </div>

    <!-- 自动完成下拉框 -->
    <AutoComplete ref="autoCompleteRef" :visible="showSuggestions" :suggestions="suggestions"
      :active-index="activeSuggestionIndex" :position="suggestionPosition" :search-term="currentSearchTerm"
      @select="insertSuggestion" @update:active-index="activeSuggestionIndex = $event" @close="hideSuggestions" />
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick, onMounted, onUnmounted } from 'vue'
import { Check, Close, Delete } from '@element-plus/icons-vue'
import AutoComplete from './AutoComplete.vue'
import type {
  ValidationResult,
  Suggestion,
  TextInsertionContext,
  TextInsertionResult,
  WordBoundary,
  Variable
} from './types'
import {
  VariableManagerImpl,
  ExampleGenerator,
  ExpressionValidatorImpl,
  AutoCompleteProviderImpl
} from './utils'

export interface ExpressionEditorProps {
  modelValue: string                    // 表达式内容
  systemVariables?: Variable[]         // 系统变量列表
  formVariables?: Variable[]           // 表单变量列表
  showVariableHelp?: boolean          // 是否显示变量提示，默认true
  showExample?: boolean               // 是否显示示例，默认true
  showSyntaxDoc?: boolean             // 是否显示语法文档，默认false
  placeholder?: string                // 输入框占位符
  readonly?: boolean                  // 是否只读
}

export interface ExpressionEditorEmits {
  'update:modelValue': [value: string]
  'validate': [result: ValidationResult]
}

// Props 定义
const props = withDefaults(defineProps<ExpressionEditorProps>(), {
  modelValue: '',
  systemVariables: () => [],
  formVariables: () => [],
  showVariableHelp: true,
  showExample: true,
  showSyntaxDoc: false,
  placeholder: '',
  readonly: false
})

// Emits 定义
const emit = defineEmits<ExpressionEditorEmits>()

// 响应式数据
const localValue = ref(props.modelValue)
const inputRef = ref()
const autoCompleteRef = ref()
const validationResult = ref<ValidationResult | null>(null)
const activeCollapse = ref(['system', 'form'])
const activeDocSection = ref(['operators'])
const showSuggestions = ref(false)
const suggestions = ref<Suggestion[]>([])
const activeSuggestionIndex = ref(0)
const suggestionPosition = ref({ x: 0, y: 0 })
const currentSearchTerm = ref('')

// 工具类实例
const variableManager = computed(() =>
  new VariableManagerImpl(props.systemVariables, props.formVariables)
)
const validator = computed(() =>
  new ExpressionValidatorImpl(variableManager.value)
)
const autoCompleteProvider = computed(() =>
  new AutoCompleteProviderImpl(variableManager.value)
)

// 计算属性
const exampleExpression = computed(() =>
  ExampleGenerator.generateExample(
    props.systemVariables || [],
    props.formVariables || []
  )
)

// 监听器
watch(() => props.modelValue, (newValue) => {
  localValue.value = newValue
})

watch(localValue, (newValue) => {
  emit('update:modelValue', newValue)
  validateExpression()
})

// 方法
const handleInput = (value: string) => {
  localValue.value = value

  // 触发自动完成
  if (!props.readonly) {
    triggerAutoComplete()
  }
}

const handleKeydown = (event: KeyboardEvent) => {
  // Ctrl+Space 触发自动完成
  if (event.ctrlKey && event.key === ' ') {
    event.preventDefault()
    triggerAutoComplete()
    return
  }

  // 如果自动完成面板显示，将键盘事件委托给AutoComplete组件
  if (showSuggestions.value && autoCompleteRef.value) {
    autoCompleteRef.value.handleKeydown(event)
    return
  }

  // 其他输入时触发自动完成
  if (!props.readonly && /^[a-zA-Z_]$/.test(event.key)) {
    // 延迟触发，让输入先完成
    nextTick(() => {
      triggerAutoComplete()
    })
  }
}

const handleFocus = () => {
  // 聚焦时的处理逻辑
}

const handleBlur = () => {
  // 延迟隐藏建议，以便点击建议项
  setTimeout(() => {
    hideSuggestions()
  }, 200)
}

const validateExpression = () => {
  // 使用完整验证功能
  const result = validator.value.validateComplete(
    localValue.value,
    variableManager.value.getAllVariables()
  )

  validationResult.value = result
  emit('validate', result)
}

const clearExpression = () => {
  localValue.value = ''
  validationResult.value = null
  hideSuggestions()
}

const insertExample = () => {
  localValue.value = exampleExpression.value
  nextTick(() => {
    inputRef.value?.focus()
  })
}

const insertVariable = (variableName: string) => {
  insertTextAtCursor(variableName)
}

// 修改 insertSuggestion 方法使用新逻辑
const insertSuggestion = (suggestion: Suggestion) => {
  insertSuggestionSafely(suggestion)
  hideSuggestions()
}

// 实现安全插入包装方法
const insertSuggestionSafely = (suggestion: Suggestion) => {
  try {
    // 验证建议对象的有效性
    if (!suggestion || !suggestion.value) {
      console.warn('无效的建议对象，跳过插入')
      return
    }

    // 为 textarea 元素实现输入验证
    const textarea = inputRef.value?.textarea || inputRef.value?.input
    if (!textarea) {
      console.warn('Textarea 元素未找到，使用直接插入')
      // 直接设置值作为回退
      localValue.value = suggestion.value
      return
    }

    const cursorPosition = textarea.selectionStart || 0
    const selectionEnd = textarea.selectionEnd || 0
    
    if (cursorPosition !== selectionEnd) {
      // 有选中文本，替换选中的文本
      const before = localValue.value.substring(0, cursorPosition)
      const after = localValue.value.substring(selectionEnd)
      localValue.value = before + suggestion.value + after
      
      // 设置光标位置在插入文本的末尾
      const newPosition = cursorPosition + suggestion.value.length
      nextTick(() => {
        textarea.setSelectionRange(newPosition, newPosition)
        textarea.focus()
      })
    } else {
      // 没有选中文本，需要检查是否应该替换部分单词
      const textBeforeCursor = localValue.value.substring(0, cursorPosition)
      const partialWord = extractCurrentWord(textBeforeCursor, cursorPosition)
      
      if (partialWord && suggestion.value.toLowerCase().startsWith(partialWord.toLowerCase())) {
        // 应该替换部分单词
        const wordStartPosition = cursorPosition - partialWord.length
        const before = localValue.value.substring(0, wordStartPosition)
        const after = localValue.value.substring(cursorPosition)
        localValue.value = before + suggestion.value + after
        
        // 设置光标位置
        let newPosition = wordStartPosition + suggestion.value.length
        
        // 为函数建议特殊处理光标位置（放在括号之间）
        if (suggestion.type === 'function' && suggestion.value.includes('()')) {
          const parenIndex = suggestion.value.indexOf('()')
          if (parenIndex !== -1) {
            newPosition = wordStartPosition + parenIndex + 1
          }
        }
        
        nextTick(() => {
          textarea.setSelectionRange(newPosition, newPosition)
          textarea.focus()
        })
      } else {
        // 直接在光标位置插入
        const before = localValue.value.substring(0, cursorPosition)
        const after = localValue.value.substring(cursorPosition)
        localValue.value = before + suggestion.value + after
        
        // 设置光标位置
        let newPosition = cursorPosition + suggestion.value.length
        
        // 为函数建议特殊处理光标位置（放在括号之间）
        if (suggestion.type === 'function' && suggestion.value.includes('()')) {
          const parenIndex = suggestion.value.indexOf('()')
          if (parenIndex !== -1) {
            newPosition = cursorPosition + parenIndex + 1
          }
        }
        
        nextTick(() => {
          textarea.setSelectionRange(newPosition, newPosition)
          textarea.focus()
        })
      }
    }
  } catch (error) {
    // 最后的回退：直接设置值
    console.error('建议插入出错，使用最简单的回退方法:', error)
    try {
      localValue.value = suggestion.value
    } catch (fallbackError) {
      console.error('回退插入也失败了:', fallbackError)
    }
  }
}

// 安全的文本插入方法（带有错误处理的回退方法）
const insertTextAtCursorSafely = (text: string) => {
  try {
    const textarea = inputRef.value?.textarea || inputRef.value?.input
    if (!textarea) {
      console.warn('Textarea 元素未找到，无法插入文本')
      return
    }

    // 验证文本输入
    if (typeof text !== 'string') {
      console.warn('插入的文本必须是字符串类型')
      return
    }

    insertTextAtCursor(text)
  } catch (error) {
    console.error('文本插入失败:', error)
    // 最后的回退：直接设置值（虽然会丢失光标位置）
    try {
      localValue.value += text
    } catch (fallbackError) {
      console.error('回退插入也失败了:', fallbackError)
    }
  }
}

const insertTextAtCursor = (text: string) => {
  const textarea = inputRef.value?.textarea || inputRef.value?.input
  if (!textarea) return

  const start = textarea.selectionStart
  const end = textarea.selectionEnd
  const before = localValue.value.substring(0, start)
  const after = localValue.value.substring(end)

  localValue.value = before + text + after

  nextTick(() => {
    const newPosition = start + text.length
    textarea.setSelectionRange(newPosition, newPosition)
    textarea.focus()
  })
}

const triggerAutoComplete = () => {
  const textarea = inputRef.value?.textarea || inputRef.value?.input
  if (!textarea) return

  const cursorPosition = textarea.selectionStart
  const textBeforeCursor = localValue.value.substring(0, cursorPosition)
  const context = textBeforeCursor

  // 提取当前输入的词
  const lastWord = extractCurrentWord(textBeforeCursor, cursorPosition)
  currentSearchTerm.value = lastWord

  if (lastWord.length < 1 && !shouldShowAllSuggestions(context)) {
    hideSuggestions()
    return
  }

  // 使用增强的智能补全功能
  suggestions.value = autoCompleteProvider.value.getAllSuggestions(lastWord, context)

  if (suggestions.value.length > 0) {
    showSuggestions.value = true
    activeSuggestionIndex.value = 0
    updateSuggestionPosition(textarea, cursorPosition)
  } else {
    hideSuggestions()
  }
}

const hideSuggestions = () => {
  showSuggestions.value = false
  suggestions.value = []
  activeSuggestionIndex.value = 0
}

const extractCurrentWord = (text: string, cursorPosition: number): string => {
  // 检查是否在日期方法上下文中
  const textBeforeCursor = text.substring(0, cursorPosition)
  // 修改正则表达式：检查是否包含 now(). 或 date(). 模式
  const dateMethodPattern = /(now\(\)|date\([^)]*\))\s*\./
  const isInDateMethodContext = dateMethodPattern.test(textBeforeCursor)
  
  // 特殊处理：如果光标前面是点号，检查是否为日期方法上下文
  if (cursorPosition > 0 && text[cursorPosition - 1] === '.') {
    if (isInDateMethodContext) {
      // 在日期方法上下文中，点号后面应该返回空字符串以触发方法建议
      return ''
    }
  }
  
  // 向前查找单词边界
  let start = cursorPosition - 1
  while (start >= 0 && /[a-zA-Z0-9_.]/.test(text[start])) {
    start--
  }
  start++

  // 向后查找单词边界
  let end = cursorPosition
  while (end < text.length && /[a-zA-Z0-9_.]/.test(text[end])) {
    end++
  }

  const currentWord = text.substring(start, cursorPosition)
  
  // 如果在日期方法上下文中，需要特殊处理单词提取
  if (isInDateMethodContext) {
    // 查找最后一个点号的位置
    const lastDotIndex = textBeforeCursor.lastIndexOf('.')
    if (lastDotIndex !== -1 && lastDotIndex < cursorPosition) {
      // 返回点号后面的部分
      return text.substring(lastDotIndex + 1, cursorPosition)
    }
  }
  
  return currentWord
}

// 获取文本插入上下文 - 增强版本
const getTextInsertionContext = (): TextInsertionContext => {
  const textarea = inputRef.value?.textarea || inputRef.value?.input
  if (!textarea) {
    return {
      cursorPosition: 0,
      partialWord: '',
      wordStartPosition: 0,
      wordEndPosition: 0,
      shouldReplace: false
    }
  }
  
  const cursorPosition = textarea.selectionStart
  const selectionEnd = textarea.selectionEnd
  
  // 验证光标位置在文本边界内
  if (!isValidCursorPosition(cursorPosition, localValue.value.length)) {
    console.warn('光标位置超出文本边界，使用安全默认值')
    return {
      cursorPosition: Math.min(cursorPosition, localValue.value.length),
      partialWord: '',
      wordStartPosition: Math.min(cursorPosition, localValue.value.length),
      wordEndPosition: Math.min(cursorPosition, localValue.value.length),
      shouldReplace: false
    }
  }
  
  // 检测是否有选中文本
  const selectedText = cursorPosition !== selectionEnd 
    ? localValue.value.substring(cursorPosition, selectionEnd)
    : undefined
  
  // 在光标位置添加单词边界检测
  const wordBoundary = extractWordAtPositionSafely(localValue.value, cursorPosition)
  
  // 实现部分单词提取逻辑
  const textBeforeCursor = localValue.value.substring(0, cursorPosition)
  const partialWord = extractPartialWordAtCursorSafely(textBeforeCursor, cursorPosition)
  
  // 处理空或仅包含空格的部分单词的边缘情况
  const cleanPartialWord = partialWord.trim()
  const shouldReplace = cleanPartialWord.length > 0 && !selectedText && isValidPartialWord(cleanPartialWord)
  
  return {
    cursorPosition,
    partialWord: cleanPartialWord,
    wordStartPosition: wordBoundary.start,
    wordEndPosition: wordBoundary.end,
    shouldReplace,
    selectedText
  }
}

// 提取光标处的部分单词
const extractPartialWordAtCursor = (textBeforeCursor: string, cursorPosition: number): string => {
  // 从光标位置向前查找单词开始
  let start = textBeforeCursor.length - 1
  
  while (start >= 0 && isWordCharacter(textBeforeCursor[start])) {
    start--
  }
  
  start++ // 调整到单词开始位置
  
  return textBeforeCursor.substring(start)
}

// 验证光标位置在文本边界内
const isValidCursorPosition = (position: number, textLength: number): boolean => {
  return position >= 0 && position <= textLength
}

// 安全的部分单词提取（带边界检查）
const extractPartialWordAtCursorSafely = (textBeforeCursor: string, cursorPosition: number): string => {
  try {
    // 验证输入参数
    if (!textBeforeCursor || typeof textBeforeCursor !== 'string') {
      return ''
    }
    
    if (cursorPosition < 0 || cursorPosition > textBeforeCursor.length) {
      console.warn('光标位置超出文本边界，返回空字符串')
      return ''
    }
    
    return extractPartialWordAtCursor(textBeforeCursor, cursorPosition)
  } catch (error) {
    console.warn('提取部分单词时出错:', error)
    return ''
  }
}

// 安全的单词边界提取（带边界检查）
const extractWordAtPositionSafely = (text: string, position: number): WordBoundary => {
  try {
    // 验证输入参数
    if (!text || typeof text !== 'string') {
      return { word: '', start: 0, end: 0 }
    }
    
    if (position < 0 || position > text.length) {
      console.warn('位置超出文本边界，返回安全默认值')
      const safePosition = Math.max(0, Math.min(position, text.length))
      return { word: '', start: safePosition, end: safePosition }
    }
    
    return extractWordAtPosition(text, position)
  } catch (error) {
    console.warn('提取单词边界时出错:', error)
    return { word: '', start: position, end: position }
  }
}

// 验证部分单词是否有效
const isValidPartialWord = (partialWord: string): boolean => {
  // 处理空或仅包含空格的部分单词的边缘情况
  if (!partialWord || partialWord.trim().length === 0) {
    return false
  }
  
  // 检查是否只包含有效的单词字符
  if (!/^[a-zA-Z_][a-zA-Z0-9_.]*$/.test(partialWord)) {
    return false
  }
  
  // 检查长度限制（避免过长的无效输入）
  if (partialWord.length > 100) {
    console.warn('部分单词过长，可能无效')
    return false
  }
  
  return true
}

// 添加无效单词开始/结束位置的检查
const validateWordBoundary = (wordBoundary: WordBoundary, textLength: number): WordBoundary => {
  const { word, start, end } = wordBoundary
  
  // 验证开始位置
  const validStart = Math.max(0, Math.min(start, textLength))
  
  // 验证结束位置
  const validEnd = Math.max(validStart, Math.min(end, textLength))
  
  // 如果位置被修正，重新提取单词
  if (validStart !== start || validEnd !== end) {
    console.warn('单词边界位置无效，已修正:', { 
      original: { start, end }, 
      corrected: { start: validStart, end: validEnd } 
    })
    
    return {
      word: validStart === validEnd ? '' : word.substring(0, validEnd - validStart),
      start: validStart,
      end: validEnd
    }
  }
  
  return wordBoundary
}

// 检测上下文类型以优化建议
const detectContextType = (textBeforeCursor: string): 'start' | 'after-operator' | 'after-space' | 'in-parentheses' | 'after-dot' => {
  const trimmed = textBeforeCursor.trim()
  
  if (trimmed === '') return 'start'
  if (/[><=!&|+\-*/]\s*$/.test(trimmed)) return 'after-operator'
  if (/\s$/.test(textBeforeCursor)) return 'after-space'
  if (/\($/.test(trimmed)) return 'in-parentheses'
  if (/\.$/.test(trimmed)) return 'after-dot'
  
  return 'start'
}

// 提取指定位置的单词及其边界 - 增强版本
const extractWordAtPosition = (text: string, position: number): WordBoundary => {
  let start = position
  let end = position

  // 如果光标在单词中间，需要向前找到单词开始
  while (start > 0 && isWordCharacter(text[start - 1])) {
    start--
  }

  // 从光标位置向后找到单词结束
  while (end < text.length && isWordCharacter(text[end])) {
    end++
  }

  return {
    word: text.substring(start, end),
    start,
    end
  }
}

// 精确单词边界检测的 findWordEnd 方法
const findWordEnd = (text: string, startPosition: number): number => {
  let end = startPosition
  
  // 使用增强的单词字符检测
  while (end < text.length && isWordCharacter(text[end])) {
    end++
  }
  
  return end
}

// 上下文感知的单词模式匹配
const isWordCharacter = (char: string): boolean => {
  // 支持变量名、函数名和属性访问的字符
  return /[a-zA-Z0-9_.]/.test(char)
}

// 检测单词是否为函数调用模式
const isFunctionPattern = (word: string): boolean => {
  return /^[a-zA-Z_][a-zA-Z0-9_]*$/.test(word)
}

// 检测单词是否为变量模式
const isVariablePattern = (word: string): boolean => {
  return /^[a-zA-Z_][a-zA-Z0-9_.]*$/.test(word)
}

// 检测单词是否为操作符模式
const isOperatorPattern = (word: string): boolean => {
  return /^[><=!&|+\-*/]+$/.test(word)
}

// 上下文感知的建议插入方法
const insertSuggestionWithContext = (
  suggestion: Suggestion, 
  context: TextInsertionContext
): TextInsertionResult => {
  const textarea = inputRef.value?.textarea || inputRef.value?.input
  if (!textarea) {
    return {
      success: false,
      newCursorPosition: 0,
      insertedText: '',
      error: 'Textarea element not found'
    }
  }

  let insertText = suggestion.value
  let newCursorPosition: number
  let replacedText: string | undefined

  try {
    // 验证和修正单词边界位置
    const validatedBoundary = validateWordBoundary(
      { word: context.partialWord, start: context.wordStartPosition, end: context.wordEndPosition },
      localValue.value.length
    )

    if (context.shouldReplace && context.partialWord && shouldReplacePartialWord(suggestion, context)) {
      // 替换部分单词模式 - 使用验证后的边界
      const before = localValue.value.substring(0, validatedBoundary.start)
      const after = localValue.value.substring(validatedBoundary.end)
      
      replacedText = context.partialWord
      localValue.value = before + insertText + after
      newCursorPosition = validatedBoundary.start + insertText.length
    } else if (context.selectedText) {
      // 替换选中文本模式 - 验证选择边界
      const selectionStart = Math.max(0, Math.min(textarea.selectionStart, localValue.value.length))
      const selectionEnd = Math.max(selectionStart, Math.min(textarea.selectionEnd, localValue.value.length))
      
      const before = localValue.value.substring(0, selectionStart)
      const after = localValue.value.substring(selectionEnd)
      
      replacedText = context.selectedText
      localValue.value = before + insertText + after
      newCursorPosition = selectionStart + insertText.length
    } else {
      // 在光标处插入模式（回退到当前行为） - 验证光标位置
      const safeCursorPosition = Math.max(0, Math.min(context.cursorPosition, localValue.value.length))
      const before = localValue.value.substring(0, safeCursorPosition)
      const after = localValue.value.substring(safeCursorPosition)
      
      localValue.value = before + insertText + after
      newCursorPosition = safeCursorPosition + insertText.length
    }

    // 应用智能光标定位
    newCursorPosition = calculateSmartCursorPosition(suggestion, insertText, newCursorPosition)

    // 验证最终光标位置
    const finalCursorPosition = Math.max(0, Math.min(newCursorPosition, localValue.value.length))

    // 设置光标位置
    nextTick(() => {
      textarea.setSelectionRange(finalCursorPosition, finalCursorPosition)
      textarea.focus()
    })

    return {
      success: true,
      newCursorPosition: finalCursorPosition,
      insertedText: insertText,
      replacedText
    }
  } catch (error) {
    return {
      success: false,
      newCursorPosition: context.cursorPosition,
      insertedText: '',
      error: error instanceof Error ? error.message : 'Unknown error'
    }
  }
}

// 判断是否应该替换部分单词
const shouldReplacePartialWord = (suggestion: Suggestion, context: TextInsertionContext): boolean => {
  if (!context.partialWord || context.partialWord.length === 0) {
    return false
  }
  
  // 如果建议值以部分单词开头，则应该替换
  const suggestionLower = suggestion.value.toLowerCase()
  const partialLower = context.partialWord.toLowerCase()
  
  return suggestionLower.startsWith(partialLower) && suggestionLower !== partialLower
}

// 计算智能光标位置
const calculateSmartCursorPosition = (
  suggestion: Suggestion, 
  insertedText: string, 
  defaultPosition: number
): number => {
  switch (suggestion.type) {
    case 'function':
      return calculateFunctionCursorPosition(insertedText, defaultPosition)
    case 'operator':
      return calculateOperatorCursorPosition(insertedText, defaultPosition)
    case 'variable':
    default:
      return calculateVariableCursorPosition(insertedText, defaultPosition)
  }
}

// 变量插入后的光标定位
const calculateVariableCursorPosition = (insertedText: string, defaultPosition: number): number => {
  // 对于变量，光标定位在变量名末尾
  return defaultPosition
}

// 函数建议的光标定位（光标在括号之间）
const calculateFunctionCursorPosition = (insertedText: string, defaultPosition: number): number => {
  // 如果函数包含括号，将光标定位在括号之间
  if (insertedText.includes('()')) {
    const parenIndex = insertedText.indexOf('()')
    if (parenIndex !== -1) {
      // 光标定位在开括号后面
      return defaultPosition - insertedText.length + parenIndex + 1
    }
  }
  
  // 如果函数只有开括号，光标定位在括号后面
  if (insertedText.endsWith('(')) {
    return defaultPosition
  }
  
  // 默认情况下，光标定位在函数名末尾
  return defaultPosition
}

// 操作符建议的光标定位和间距
const calculateOperatorCursorPosition = (insertedText: string, defaultPosition: number): number => {
  // 对于操作符，通常在操作符后面添加空格，光标定位在空格后
  // 这里假设操作符插入时已经包含了适当的间距
  return defaultPosition
}

const shouldShowAllSuggestions = (context: string): boolean => {
  // 在某些上下文中显示所有建议，比如刚输入操作符后
  const trimmedContext = context.trim()
  
  // 检查是否在日期方法上下文中（如 now(). 或 date().）
  const dateMethodPattern = /(now\(\)|date\([^)]*\))\s*\.\s*$/
  if (dateMethodPattern.test(trimmedContext)) {
    return true
  }
  
  return /[><=!&|]\s*$/.test(trimmedContext) || trimmedContext === ''
}

const updateSuggestionPosition = (textarea: HTMLTextAreaElement, cursorPosition: number) => {
  // 获取textarea的位置信息
  const rect = textarea.getBoundingClientRect()

  // 简化的位置计算 - 在实际项目中可能需要更精确的光标位置计算
  const lineHeight = 20 // 估算的行高
  const lines = textarea.value.substring(0, cursorPosition).split('\n')
  const currentLine = lines.length - 1
  const currentColumn = lines[lines.length - 1].length

  suggestionPosition.value = {
    x: rect.left + Math.min(currentColumn * 8, rect.width - 200), // 8px per character estimate
    y: rect.top + (currentLine + 1) * lineHeight + 5
  }
}

// 生命周期
onMounted(() => {
  validateExpression()
})

onUnmounted(() => {
  // 清理工作
})

// 暴露方法给测试使用
defineExpose({
  insertSuggestionSafely,
  insertSuggestionWithContext,
  triggerAutoComplete,
  localValue,
  showSuggestions,
  suggestions
})
</script>

<style scoped>
.expression-editor {
  position: relative;
  width: 100%;
}

.expression-input-container {
  position: relative;
}

.expression-input {
  width: 100%;
}

.validation-indicator {
  position: absolute;
  right: 8px;
  top: 8px;
}

.success-icon {
  color: #67c23a;
}

.error-icon {
  color: #f56c6c;
}

.action-buttons {
  margin-top: 8px;
  display: flex;
  gap: 8px;
}

.validation-messages {
  margin-top: 8px;
}

.error-messages {
  margin-bottom: 8px;
}

.warning-messages {
  margin-bottom: 8px;
}

.variable-help {
  margin-top: 16px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
}

.variable-list {
  padding: 4px;
}

.variable-item {
  display: flex;
  align-items: center;
  padding: 2px 6px;
  cursor: pointer;
  border-radius: 3px;
  transition: background-color 0.2s;
  font-size: 13px;
  line-height: 1.3;
}

.variable-item:hover {
  background-color: #f5f7fa;
}

.variable-name {
  font-weight: 500;
  color: #409eff;
  margin-right: 6px;
}

.variable-label {
  color: #909399;
  margin-right: 6px;
  font-size: 12px;
}

.variable-type {
  font-size: 11px;
  color: #c0c4cc;
  margin-left: auto;
}

.expression-example {
  margin-top: 16px;
  padding: 12px;
  background-color: #f5f7fa;
  border-radius: 4px;
}

.example-title {
  font-size: 14px;
  color: #606266;
  margin-bottom: 8px;
}

.example-content {
  cursor: pointer;
  padding: 8px;
  background-color: #fff;
  border-radius: 4px;
  border: 1px solid #e4e7ed;
  transition: border-color 0.2s;
}

.example-content:hover {
  border-color: #409eff;
}

.example-content code {
  color: #e6a23c;
  font-family: 'Courier New', monospace;
}

.suggestions-dropdown {
  position: absolute;
  background: white;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  max-height: 200px;
  overflow-y: auto;
  min-width: 200px;
}

.suggestion-item {
  padding: 8px 12px;
  cursor: pointer;
  border-bottom: 1px solid #f0f0f0;
  transition: background-color 0.2s;
}

.suggestion-item:hover,
.suggestion-item.active {
  background-color: #f5f7fa;
}

.suggestion-item:last-child {
  border-bottom: none;
}

.suggestion-label {
  font-weight: 500;
  color: #303133;
}

.suggestion-type {
  font-size: 12px;
  color: #909399;
  margin-left: 8px;
  padding: 2px 6px;
  background-color: #f0f2f5;
  border-radius: 2px;
}

.suggestion-description {
  font-size: 12px;
  color: #606266;
  margin-top: 4px;
}

.syntax-documentation {
  margin-top: 16px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
}

.doc-content {
  padding: 12px;
}

.doc-content ul {
  margin: 0;
  padding-left: 20px;
}

.doc-content li {
  margin-bottom: 8px;
  line-height: 1.5;
}

.doc-content code {
  background-color: #f5f7fa;
  color: #e6a23c;
  padding: 2px 6px;
  border-radius: 3px;
  font-family: 'Courier New', monospace;
  font-size: 13px;
}

.doc-content h5 {
  margin: 16px 0 8px 0;
  color: #303133;
  font-size: 14px;
  font-weight: 600;
}

.doc-content h5:first-child {
  margin-top: 0;
}
</style>